'use strict';

const Service = require('egg').Service;
const User = require('../model/user');
const TravelNote = require('../model/travelNote');
const City = require('../model/city');
const TravelPlan = require('../model/travel_plan');
const { Op, fn, col, literal } = require('sequelize');

class DashboardService extends Service {
  /**
   * 获取仪表盘基础统计数据
   */
  async getStats() {
    try {
      // 用户总数
      const totalUsers = await User.count();

      // 游记总数
      const totalNotes = await TravelNote.count();

      // 旅行计划总数
      const totalPlans = await TravelPlan.count();

      // 城市总数
      const totalCities = await City.count();

      // 本周新增用户
      const weekAgo = new Date();
      weekAgo.setDate(weekAgo.getDate() - 7);
      const weekNewUsers = await User.count({
        where: {
          created_at: {
            [Op.gte]: weekAgo
          }
        }
      });

      // 本周新增游记
      const weekNewNotes = await TravelNote.count({
        where: {
          created_at: {
            [Op.gte]: weekAgo
          }
        }
      });

      // 计算增长率
      const userGrowthRate = totalUsers > 0 ? ((weekNewUsers / totalUsers) * 100).toFixed(1) : 0;
      const noteGrowthRate = totalNotes > 0 ? ((weekNewNotes / totalNotes) * 100).toFixed(1) : 0;

      return {
        totalUsers,
        totalNotes,
        totalPlans,
        totalCities,
        weekNewUsers,
        weekNewNotes,
        userGrowthRate: `+${userGrowthRate}%`,
        noteGrowthRate: `+${noteGrowthRate}%`
      };
    } catch (error) {
      this.ctx.logger.error('获取统计数据失败:', error);
      throw error;
    }
  }

  /**
   * 获取热门城市TOP10（按推荐数排序）
   */
  async getTopCities() {
    try {
      const cities = await City.findAll({
        order: [['recommendations', 'DESC']],
        limit: 10,
        attributes: ['id', 'name', 'recommendations']
      });

      return cities.map(city => ({
        name: city.name,
        value: city.recommendations || 0
      }));
    } catch (error) {
      this.ctx.logger.error('获取热门城市排行失败:', error);
      throw error;
    }
  }

  /**
   * 获取平台活跃度趋势（按月统计）
   * 统计游记浏览量和发布量
   */
  async getActivityTrend() {
    try {
      const currentYear = new Date().getFullYear();
      const months = [];
      const viewData = [];
      const postData = [];

      // 获取最近12个月的数据
      for (let i = 11; i >= 0; i--) {
        const date = new Date();
        date.setMonth(date.getMonth() - i);
        const month = date.getMonth() + 1;
        const year = date.getFullYear();

        months.push(`${month}月`);

        // 该月的开始和结束时间
        const startDate = new Date(year, month - 1, 1);
        const endDate = new Date(year, month, 0, 23, 59, 59);

        // 统计该月游记发布量
        const monthPosts = await TravelNote.count({
          where: {
            created_at: {
              [Op.between]: [startDate, endDate]
            }
          }
        });

        // 统计该月游记浏览量总和
        const monthViews = await TravelNote.sum('view_count', {
          where: {
            created_at: {
              [Op.between]: [startDate, endDate]
            }
          }
        }) || 0;

        postData.push(monthPosts);
        viewData.push(Math.floor(monthViews));
      }

      return {
        months,
        viewData,
        postData
      };
    } catch (error) {
      this.ctx.logger.error('获取平台活跃度趋势失败:', error);
      throw error;
    }
  }

  /**
   * 获取用户增长趋势（按周统计最近7天）
   * 活跃用户定义：7天内有发布游记或旅行计划的用户
   */
  async getUserGrowth() {
    try {
      const days = [];
      const newUserData = [];
      const activeUserData = [];

      // 获取最近7天的数据
      for (let i = 6; i >= 0; i--) {
        const date = new Date();
        date.setDate(date.getDate() - i);
        const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
        days.push(dayNames[date.getDay()]);

        // 该天的开始和结束时间
        const startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
        const endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59);

        // 统计该天新增用户
        const dayNewUsers = await User.count({
          where: {
            created_at: {
              [Op.between]: [startDate, endDate]
            }
          }
        });

        // 统计该天活跃用户（发布了游记或旅行计划）
        const activeUserIds = new Set();

        // 发布游记的用户
        const noteUsers = await TravelNote.findAll({
          where: {
            created_at: {
              [Op.between]: [startDate, endDate]
            }
          },
          attributes: ['user_id'],
          raw: true
        });
        noteUsers.forEach(note => {
          if (note.user_id) activeUserIds.add(note.user_id);
        });

        // 发布旅行计划的用户
        const planUsers = await TravelPlan.findAll({
          where: {
            created_at: {
              [Op.between]: [startDate, endDate]
            }
          },
          attributes: ['user_id'],
          raw: true
        });
        planUsers.forEach(plan => {
          if (plan.user_id) activeUserIds.add(plan.user_id);
        });

        newUserData.push(dayNewUsers);
        activeUserData.push(activeUserIds.size);
      }

      return {
        days,
        newUserData,
        activeUserData
      };
    } catch (error) {
      this.ctx.logger.error('获取用户增长趋势失败:', error);
      throw error;
    }
  }

  /**
   * 获取内容分类统计
   * 统计游记、旅行计划、城市推荐数量
   */
  async getContentCategory() {
    try {
      // 游记数量
      const noteCount = await TravelNote.count();

      // 旅行计划数量
      const planCount = await TravelPlan.count();

      // 城市推荐数（所有城市的推荐数总和）
      const cityRecommendSum = await City.sum('recommendations') || 0;

      return [
        { name: '游记', value: noteCount },
        { name: '旅行计划', value: planCount },
        { name: '城市推荐', value: Math.floor(cityRecommendSum) }
      ];
    } catch (error) {
      this.ctx.logger.error('获取内容分类统计失败:', error);
      throw error;
    }
  }
}

module.exports = DashboardService;

